Micron Document
NexusPi Git Node

Commit ebe2bd6c95f6813afd645614d2bcf6d871d865a9


Parents : f0aee06
Author : Chad Attermann <attermann@gmail.com>
Date : 2026-06-24T11:23:37-06:00

Extension and enhancement of Provisioning fields

Changes

5 files changed, 111 insertions(+), 69 deletions(-)

M Pages.h +1 -1
M Provisioning.cpp +47 -39

Diff

diff --git a/Pages.h b/Pages.h
index a0aa223..5224880 100644
--- a/Pages.h
+++ b/Pages.h
@@ -183,7 +183,7 @@ RNS::Bytes serve_page(
destination_path_responses += destination.path_responses().size();
}
uint32_t interface_announces = 0;
- for (auto& [interface_hash, interface] : RNS::Transport::get_interfaces()) {
+ for (auto& interface : RNS::Transport::get_interfaces()) {
interface_announces += interface.announce_queue().size();
}

diff --git a/Provisioning.cpp b/Provisioning.cpp
index d1086de..83a7675 100644
--- a/Provisioning.cpp
+++ b/Provisioning.cpp
@@ -42,12 +42,13 @@
// operator bool() returns true only after setup() assigns it a real
// LoRaInterface implementation — so a single runtime check works in
// both compile configurations.
+#if defined(LORA_TRANSPORT)
extern RNS::Interface lora_interface;
+extern uint32_t lora_freq;
+extern uint32_t lora_bw;
extern int lora_sf;
extern int lora_cr;
extern int lora_txp;
-extern uint32_t lora_bw;
-extern uint32_t lora_freq;
extern uint32_t lora_bitrate;
extern uint8_t implicit_l;
extern int noise_floor;
@@ -55,6 +56,9 @@ extern int current_rssi;
extern int last_rssi;
extern uint8_t last_rssi_raw;
extern uint8_t last_snr_raw;
+extern float st_airtime_limit;
+extern float lt_airtime_limit;
+#endif
#if defined(UDP_TRANSPORT)
// udp_interface is only declared in RNode_Firmware.ino under UDP_TRANSPORT,
// so this extern (and its dependents) must stay behind the same guard.
@@ -112,16 +116,16 @@ static void register_provisioning_namespaces() {
// ----- General namespace -----
auto general = Provisioner::instance()
.register_namespace("RNode General Config", PROV_NS_GENERAL)
- .field_bool("kiss_framed_logs", PROV_GENERAL_KISS_LOG, FF_LIVE_APPLY, kiss_framed_logs,
+ .field_bool("Kiss Framed Logs", PROV_GENERAL_KISS_LOG, FF_LIVE_APPLY, kiss_framed_logs,
[](const Value& v) { kiss_framed_logs = v.as_bool(); return true; },
[]() { return kiss_framed_logs; });
#ifdef URTN_STATS_PAGES
general
- .field_bool("nomadnet_enabled", PROV_GENERAL_NOMADNET_ENABLE, FF_REBOOT_REQUIRED, nomadnet_enabled,
+ .field_bool("NomadNet Enabled", PROV_GENERAL_NOMADNET_ENABLE, FF_REBOOT_REQUIRED, nomadnet_enabled,
[](const Value& v) { nomadnet_enabled = v.as_bool(); return true; },
[]() { return nomadnet_enabled; })
- .field_string("nomadnet_name", PROV_GENERAL_NOMADNET_NAME, FF_REBOOT_REQUIRED, nomadnet_name, sizeof(nomadnet_name)-1,
+ .field_string("NomadNet Name", PROV_GENERAL_NOMADNET_NAME, FF_REBOOT_REQUIRED, nomadnet_name, sizeof(nomadnet_name)-1,
[](const Value& v) { strncpy(nomadnet_name, v.as_string().c_str(), sizeof(nomadnet_name)); return true; },
[]() { return nomadnet_name; });
#endif
@@ -130,7 +134,7 @@ static void register_provisioning_namespaces() {
if (lora_interface) {
general
.field_enum(
- "lora_interface_mode", PROV_GENERAL_LORA_MODE, FF_LIVE_APPLY, static_cast<fint_t>(lora_interface.mode()),
+ "LoRa Interface Mode", PROV_GENERAL_LORA_MODE, FF_LIVE_APPLY, static_cast<fint_t>(lora_interface.mode()),
/* values */ {
RNS::Type::Interface::MODE_GATEWAY,
RNS::Type::Interface::MODE_FULL,
@@ -160,7 +164,7 @@ static void register_provisioning_namespaces() {
if (udp_interface) {
general
.field_enum(
- "udp_interface_mode", PROV_GENERAL_UDP_MODE, FF_LIVE_APPLY, static_cast<fint_t>(udp_interface.mode()),
+ "UDP Interface Mode", PROV_GENERAL_UDP_MODE, FF_LIVE_APPLY, static_cast<fint_t>(udp_interface.mode()),
/* values */ {
RNS::Type::Interface::MODE_GATEWAY,
RNS::Type::Interface::MODE_FULL,
@@ -186,10 +190,6 @@ static void register_provisioning_namespaces() {
}
#endif
- //general
- // .command_void("reboot", PROV_GENERAL_REBOOT,
- // []() { hard_reset(); return true; });
-
general
.end(); // close "General"
@@ -204,10 +204,10 @@ static void register_provisioning_namespaces() {
metrics.register_namespace("Device", PROV_NS_METRICS_DEV)
//.metric_string("transport_identity", PROV_METRICS_DEV_VER, []() { return std::to_string(MAJ_VERS) + "." + std::to_string(MIN_VERS); })
- .metric_float("battery_voltage", PROV_METRICS_DEV_BATV, []() { return battery_voltage; })
- .metric_float("battery_percent", PROV_METRICS_DEV_BATP, []() { return battery_percent; })
+ .metric_float("Battery Voltage", PROV_METRICS_DEV_BATV, []() { return battery_voltage; })
+ .metric_float("Battery Percent", PROV_METRICS_DEV_BATP, []() { return battery_percent; })
/*
- .metric_string("battery_state", PROV_METRICS_DEV_BATS, []() {
+ .metric_string("Battery State", PROV_METRICS_DEV_BATS, []() {
switch (battery_state) {
case BATTERY_STATE_CHARGING:
return "CHARGING";
@@ -224,10 +224,10 @@ static void register_provisioning_namespaces() {
.end();
metrics.register_namespace("Addresses", PROV_NS_METRICS_ADDRS)
- .metric_bytes("transport_identity", PROV_METRICS_TRANS_ID, []() { return RNS::Transport::identity() ? RNS::Transport::identity().hash() : RNS::Bytes{}; })
- .metric_bytes("probe_destination", PROV_METRICS_PROBE_DST, []() { return RNS::Transport::probe_destination() ? RNS::Transport::probe_destination().hash() : RNS::Bytes{}; })
- .metric_bytes("mgmt_destination", PROV_METRICS_MGMT_DST, []() { return RNS::Transport::remote_management_destination() ? RNS::Transport::remote_management_destination().hash() : RNS::Bytes{}; })
- .metric_bytes("nomadnet_destination", PROV_METRICS_NOMAD_DST, []() { return nomadnet_destination ? nomadnet_destination.hash() : RNS::Bytes{}; })
+ .metric_bytes("Transport Identity", PROV_METRICS_TRANS_ID, []() { return RNS::Transport::identity() ? RNS::Transport::identity().hash() : RNS::Bytes{}; })
+ .metric_bytes("Probe Destination", PROV_METRICS_PROBE_DST, []() { return RNS::Transport::probe_destination() ? RNS::Transport::probe_destination().hash() : RNS::Bytes{}; })
+ .metric_bytes("Mgmt Destination", PROV_METRICS_MGMT_DST, []() { return RNS::Transport::remote_management_destination() ? RNS::Transport::remote_management_destination().hash() : RNS::Bytes{}; })
+ .metric_bytes("NomadNet Destination", PROV_METRICS_NOMAD_DST, []() { return nomadnet_destination ? nomadnet_destination.hash() : RNS::Bytes{}; })
.end();
auto metrics_ifaces = metrics.register_namespace("Interfaces", PROV_NS_METRICS_IFACE);
@@ -236,16 +236,18 @@ static void register_provisioning_namespaces() {
metrics_ifaces
//.register_namespace("LoRa", PROV_NS_IFACE_LORA)
.register_namespace(lora_interface.name().c_str(), PROV_NS_IFACE_LORA)
- .metric_int("frequency", PROV_METRICS_LORA_FREQ, []() { return lora_freq; })
- .metric_int("bandwidth", PROV_METRICS_LORA_BW, []() { return lora_bw; })
- .metric_int("spreading_factor", PROV_METRICS_LORA_SF, []() { return lora_sf; })
- .metric_int("coding_rate", PROV_METRICS_LORA_CR, []() { return lora_cr; })
- .metric_int("tx_power", PROV_METRICS_LORA_TXP, []() { return lora_txp; })
- //.metric_int("current_rssi", PROV_METRICS_LORA_CRSSI, []() { return last_rssi+rssi_offset; })
- .metric_int("current_rssi", PROV_METRICS_LORA_CRSSI, []() { return current_rssi; })
- .metric_int("noise_floor", PROV_METRICS_LORA_NF, []() { return noise_floor; })
- .metric_int("last_rssi", PROV_METRICS_LORA_LRSSI, []() { return last_rssi+157; })
- .metric_int("last_snr", PROV_METRICS_LORA_LSNR, []() { return last_snr_raw; })
+ .metric_int("Frequency", PROV_METRICS_LORA_FREQ, []() { return lora_freq; })
+ .metric_int("Bandwidth", PROV_METRICS_LORA_BW, []() { return lora_bw; })
+ .metric_int("Spreading Factor", PROV_METRICS_LORA_SF, []() { return lora_sf; })
+ .metric_int("Coding Rate", PROV_METRICS_LORA_CR, []() { return lora_cr; })
+ .metric_int("TX Power", PROV_METRICS_LORA_TXP, []() { return lora_txp; })
+ //.metric_int("Current RSSI", PROV_METRICS_LORA_CRSSI, []() { return last_rssi+rssi_offset; })
+ .metric_int("Current RSSI", PROV_METRICS_LORA_CRSSI, []() { return current_rssi; })
+ .metric_int("Noise Floor", PROV_METRICS_LORA_NF, []() { return noise_floor; })
+ .metric_int("Last RSSI", PROV_METRICS_LORA_LRSSI, []() { return last_rssi+157; })
+ .metric_int("Last SNR", PROV_METRICS_LORA_LSNR, []() { return last_snr_raw; })
+ .metric_float("ST Airtime Limit", PROV_METRICS_LORA_STAL, []() { return st_airtime_limit; })
+ .metric_float("LT Airtime Limit", PROV_METRICS_LORA_LTAL, []() { return lt_airtime_limit; })
.end();
}
#endif
@@ -253,7 +255,7 @@ static void register_provisioning_namespaces() {
if (udp_interface) {
metrics_ifaces
//.register_namespace("UDP", PROV_NS_IFACE_UDP)
- .register_namespace(udp_interface.name().c_str(), PROV_NS_IFACE_LORA)
+ .register_namespace(udp_interface.name().c_str(), PROV_NS_IFACE_UDP)
.metric_string("ip_addr", PROV_METRICS_UDP_ADDR, []() { return wr_device_ip.toString().c_str(); })
.metric_int("udp_port", PROV_METRICS_UDP_PORT, []() { return udp_port; })
.metric_string("wifi_ssid", PROV_METRICS_WIFI_SSID, []() { return wr_ssid; })
@@ -274,24 +276,30 @@ static void register_provisioning_namespaces() {
// std::vector<fint_t>{ (fint_t)MODE_HOST, (fint_t)MODE_TNC },
// std::vector<std::string>{ "host", "tnc" },
// [](const Value& v) { op_mode = (uint8_t)v.as_int(); return true; })
- .field_int("frequency", PROV_RADIO_FREQ, FF_REBOOT_REQUIRED,
+ .field_int("Frequency", PROV_RADIO_FREQ, FF_REBOOT_REQUIRED,
(fint_t)lora_freq, (fint_t)100000000, (fint_t)1000000000,
[](const Value& v) { lora_freq = (uint32_t)v.as_int(); return true; })
- .field_int("bandwidth", PROV_RADIO_BW, FF_REBOOT_REQUIRED,
+ .field_int("Bandwidth", PROV_RADIO_BW, FF_REBOOT_REQUIRED,
(fint_t)lora_bw, (fint_t)7800, (fint_t)500000,
[](const Value& v) { lora_bw = (uint32_t)v.as_int(); return true; })
- .field_int("sf", PROV_RADIO_SF, FF_REBOOT_REQUIRED,
+ .field_int("Spreading Factor", PROV_RADIO_SF, FF_REBOOT_REQUIRED,
(fint_t)lora_sf, (fint_t)5, (fint_t)12,
[](const Value& v) { lora_sf = (int)v.as_int(); return true; })
- .field_int("cr", PROV_RADIO_CR, FF_REBOOT_REQUIRED,
+ .field_int("Coding Rate", PROV_RADIO_CR, FF_REBOOT_REQUIRED,
(fint_t)lora_cr, (fint_t)5, (fint_t)8,
[](const Value& v) { lora_cr = (int)v.as_int(); return true; })
- .field_int("txp", PROV_RADIO_TXP, FF_REBOOT_REQUIRED,
+ .field_int("TX Power", PROV_RADIO_TXP, FF_REBOOT_REQUIRED,
(fint_t)lora_txp, (fint_t)-9, (fint_t)22,
[](const Value& v) { lora_txp = (int)v.as_int(); return true; })
- .field_int("implicit_l", PROV_RADIO_IMPLICIT, FF_REBOOT_REQUIRED,
+ .field_int("Implicit Length", PROV_RADIO_IMPLICIT, FF_REBOOT_REQUIRED,
(fint_t)implicit_l, (fint_t)0, (fint_t)255,
[](const Value& v) { implicit_l = (uint8_t)v.as_int(); return true; })
+ .field_float("ST Airtime Limit", PROV_RADIO_STAL, FF_LIVE_APPLY,
+ (ffloat_t)st_airtime_limit, (fint_t)0, (fint_t)1.0,
+ [](const Value& v) { st_airtime_limit = (uint32_t)v.as_float(); return true; })
+ .field_float("LT Airtime Limit", PROV_RADIO_LTAL, FF_LIVE_APPLY,
+ (ffloat_t)lt_airtime_limit, (fint_t)0, (fint_t)1.0,
+ [](const Value& v) { lt_airtime_limit = (uint32_t)v.as_float(); return true; })
.on_commit([](Namespace& ns) {
//TRACE("[provision] Radio commit\n");
Value v;
@@ -333,16 +341,16 @@ static void register_provisioning_namespaces() {
//if (wifi_mode != WR_WIFI_OFF && udp_interface) {
Provisioner::instance()
.register_namespace("RNode Network Config", PROV_NS_NETWORK)
- .field_string("ip_addr", PROV_NET_IP, FF_REBOOT_REQUIRED,
+ .field_string("IP Address", PROV_NET_IP, FF_REBOOT_REQUIRED,
wr_device_ip.toString().c_str(), 15,
[](const Value& v) { /*wr_device_ip = v.as_string();*/ return true; })
- .field_int("udp_port", PROV_NET_PORT, FF_REBOOT_REQUIRED,
+ .field_int("UDP Port", PROV_NET_PORT, FF_REBOOT_REQUIRED,
(fint_t)udp_port, (fint_t)1024, (fint_t)65535,
[](const Value& v) { udp_port = (uint32_t)v.as_int(); return true; })
- .field_string("wifi_ssid", PROV_NET_SSID, FF_REBOOT_REQUIRED,
+ .field_string("WiFi SSID", PROV_NET_SSID, FF_REBOOT_REQUIRED,
wr_ssid, 32,
[](const Value& v) { strncpy(wr_ssid, v.as_string().c_str(), sizeof(wr_ssid)); return true; })
- .field_string("wifi_mode", PROV_NET_MODE, FF_REBOOT_REQUIRED,
+ .field_string("WiFi Mode", PROV_NET_MODE, FF_REBOOT_REQUIRED,
std::to_string(wifi_mode).c_str(), 0,
[](const Value& v) { return true; })
.end();

diff --git a/Provisioning.h b/Provisioning.h
index 7786012..50c5b51 100644
--- a/Provisioning.h
+++ b/Provisioning.h
@@ -55,7 +55,6 @@
#define PROV_GENERAL_UDP_MODE 3
#define PROV_GENERAL_NOMADNET_ENABLE 4
#define PROV_GENERAL_NOMADNET_NAME 5
-#define PROV_GENERAL_REBOOT 100
#define PROV_METRICS_TRANS_ID 1
#define PROV_METRICS_PROBE_DST 2
@@ -76,6 +75,8 @@
#define PROV_METRICS_LORA_NF 7
#define PROV_METRICS_LORA_LRSSI 8
#define PROV_METRICS_LORA_LSNR 9
+#define PROV_METRICS_LORA_STAL 10
+#define PROV_METRICS_LORA_LTAL 11
#define PROV_METRICS_UDP_ADDR 1
#define PROV_METRICS_UDP_PORT 2
@@ -88,6 +89,8 @@
#define PROV_RADIO_CR 5
#define PROV_RADIO_TXP 6
#define PROV_RADIO_IMPLICIT 7
+#define PROV_RADIO_STAL 8
+#define PROV_RADIO_LTAL 9
#define PROV_NET_IP 1
#define PROV_NET_PORT 2

diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino
index ed2626c..ca938d3 100644
--- a/RNode_Firmware.ino
+++ b/RNode_Firmware.ino
@@ -232,6 +232,7 @@ RNS::Interface udp_interface(RNS::Type::NONE);
microStore::FileSystem filesystem{microStore::Adapters::PosixFileSystem()};
#endif
#else // RNS_USE_FS
+ #include <microStore/Adapters/NoopFileSystem.h>
microStore::FileSystem filesystem{microStore::Adapters::NoopFileSystem()};
#endif // RNS_USE_FS
#endif // HAS_RNS
@@ -360,6 +361,32 @@ int _write(int file, char *ptr, int len) {
return wrote;
}
+#if defined(RNS_USE_FS)
+void dump_filesystem(const char* basepath, uint8_t level = 0) {
+ char prefix[17] = "";
+ for (uint8_t index = 0; index < level && index < 8; index++) {
+ prefix[index*2] = ' ';
+ prefix[index*2+1] = ' ';
+ prefix[index*2+2] = '\0';
+ }
+ filesystem.listDirectory(basepath, [&](const char* name) -> void {
+ // Adapter callbacks receive bare basenames — join with basepath before
+ // re-querying or recursing, and avoid emitting "//" when basepath is "/".
+ char fullpath[96];
+ const bool root = (basepath[0] == '/' && basepath[1] == '\0');
+ if (root) snprintf(fullpath, sizeof(fullpath), "/%s", name);
+ else snprintf(fullpath, sizeof(fullpath), "%s/%s", basepath, name);
+ if (filesystem.isDirectory(fullpath)) {
+ TRACEF("%s%s:", prefix, name);
+ dump_filesystem(fullpath, level + 1);
+ }
+ else {
+ TRACEF("%s%s", prefix, name);
+ }
+ });
+}
+#endif
+
void setup() {
// Initialise serial communication
@@ -784,23 +811,32 @@ void setup() {
// Finaly attempt to initialize internl flash
TRACE("Using internal flash...");
filesystem = microStore::Adapters::InternalFSFileSystem();
- filesystem.init();
- TRACE("Initialized internal flash");
+ if (!filesystem.init()) WARNING("Failed to initialize filesystem!");
+ else TRACE("Initialized internal flash");
}
#else
- filesystem.init();
- TRACE("Initialized filesystem");
+ if (!filesystem.init()) WARNING("Failed to initialize filesystem!");
#endif
// Remove legacy files
- if (filesystem.exists("/destination_table")) filesystem.remove("/destination_table");
- if (filesystem.isDirectory("/cache")) {
- filesystem.listDirectory("/cache", [&](const char* path) -> void {
+ filesystem.remove("./destination_table");
+ filesystem.remove("./path_store_index.dat");
+ filesystem.remove("./path_store_0.dat");
+ filesystem.remove("./path_store_1.dat");
+ filesystem.remove("./path_store_2.dat");
+ filesystem.remove("./path_store_3.dat");
+ filesystem.remove("./path_store_4.dat");
+ filesystem.remove("./path_store_5.dat");
+ filesystem.remove("./path_store_6.dat");
+ filesystem.remove("./path_store_7.dat");
+ if (filesystem.isDirectory("./cache")) {
+ filesystem.listDirectory("./cache", [&](const char* name) -> void {
char rmpath[64];
- snprintf(rmpath, 64, "/cache/%s", path);
- filesystem.remove(rmpath);
+ snprintf(rmpath, sizeof(rmpath), "./cache/%s", name);
+ if (filesystem.isDirectory(rmpath)) filesystem.rmdir(rmpath);
+ else filesystem.remove(rmpath);
});
- filesystem.rmdir("/cache");
+ filesystem.rmdir("./cache");
}
#if PLATFORM != PLATFORM_NATIVE
@@ -808,16 +844,16 @@ void setup() {
if (filesystem.storageAvailable() < 1024) {
WARNING("FileSystem is full, clearing space...");
// CBA Delete the path store index file to force a rebuild
- filesystem.remove("/path_store_index.dat");
+ filesystem.remove("/path_store/index.dat");
// CBA Remove all path store data files
- filesystem.remove("/path_store_0.dat");
- filesystem.remove("/path_store_1.dat");
- filesystem.remove("/path_store_2.dat");
- filesystem.remove("/path_store_3.dat");
- filesystem.remove("/path_store_4.dat");
- filesystem.remove("/path_store_5.dat");
- filesystem.remove("/path_store_6.dat");
- filesystem.remove("/path_store_7.dat");
+ filesystem.remove("/path_store/seg0.dat");
+ filesystem.remove("/path_store/seg1.dat");
+ filesystem.remove("/path_store/seg2.dat");
+ filesystem.remove("/path_store/seg3.dat");
+ filesystem.remove("/path_store/seg4.dat");
+ filesystem.remove("/path_store/seg5.dat");
+ filesystem.remove("/path_store/seg6.dat");
+ filesystem.remove("/path_store/seg7.dat");
}
#endif
@@ -829,14 +865,8 @@ void setup() {
filesystem.format();
#endif
#if 1
- TRACE("Listing filesystem /:");
- filesystem.listDirectory("/", [&](const char* path) -> void {
- TRACEF(" %s", path);
- });
- TRACE("Listing filesystem /config/:");
- filesystem.listDirectory("/config/", [&](const char* path) -> void {
- TRACEF(" %s", path);
- });
+ TRACE("Listing filesystem...");
+ dump_filesystem("./", 1);
#endif
#endif // !NDEBUG && RNS_USE_FS

diff --git a/platformio.ini b/platformio.ini
index 97ef5e1..a5cd42f 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -74,7 +74,6 @@ build_flags =
-DRNS_DEBUG_METRICS ; Enable stack metrics logs
;-DRNS_DEBUG_PATHSTORE ; Enable path store metrics logs
-DRNS_USE_FS ; Enable filesystem utilization
- -DRNS_PERSIST_PATHS ; Enable persistent storage of paths (also requires RNS_USE_FS)
-DURTN_STATS_PAGES ; Enable NomadNet stats pages
-DMSGPACK_USE_BOOST=OFF
-DDEBUGLOG_DEFAULT_LOG_LEVEL_ERROR
@@ -1019,6 +1018,7 @@ build_flags =
;-DRNS_PSRAM_POOL_BUFFER_SIZE=2048000
;-DRNS_PSRAM_POOL_BUFFER_SIZE=2000000
;-DRNS_PSRAM_POOL_BUFFER_SIZE=1000000
+ ;-DUSTORE_ENABLE_LOG
-DUSTORE_USE_POSIXFS=1
-DURTN_PATH_TABLE_MAX_RECS=2000
-DRNS_PATH_TABLE_SEGMENT_SIZE=98304 ; 96 KB
@@ -1118,6 +1118,7 @@ build_flags =
-DRNS_HEAP_POOL_BUFFER_SIZE=131072
;-DRNS_HEAP_POOL_BUFFER_SIZE=65536
;-UHAS_RNS
+ ;-DUSTORE_ENABLE_LOG
-DUSTORE_USE_INTERNALFS
-DUSTORE_USE_FLASHFS
-DURTN_PATH_TABLE_MAX_RECS=25

Served by rngit 1.5.4 - Generated in 0.03s